﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using DapperExtensions;
using log4net;

namespace DataServer.Dao
{
    public class BaseDao<T> where T : class
    {
        private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
       
        /// <summary>
        /// 打开数据库连接
        /// </summary>
        /// <returns></returns>
        protected ConnectResult OpenDbConnection()
        {
            return ConnectionPool.GetConnection();
        }
        /// <summary>
        /// 关闭数据库连接
        /// </summary>
        /// <returns></returns>
        protected void CloseDbConnection(string key)
        {
            ConnectionPool.ReleaseConnection(key);
        }


        
        /// <summary>
        /// 获取数据表名称
        /// </summary>
        /// <returns></returns>
        protected virtual string GetTableName()
        {
            return typeof(T).ToString();
        }
        /// <summary>
        /// 获取表中所有数据
        /// </summary>
        /// <returns></returns>
        public virtual List<T> GetEntities()
        {
            ConnectResult result = null;
            try
            {
                result = OpenDbConnection();
                // 并行模式下会报错 There is already an open DataReader associated with this Command which must be closed first
                // 原因是Dapper 中的协程
                return result?.Connection.GetAll<T>().ToList();
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message);
                return null;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 根据Id获取数据 NotImplemented
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual T GetEntity(long id)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 根据sql语句获取数据
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        protected virtual List<T> GetEntities(string sql)
        {
            ConnectResult result = null;
            try
            {
                if (string.IsNullOrEmpty(sql))
                    return null;
                result = OpenDbConnection();
                return result?.Connection.GetList<T>(sql).ToList();
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message);
                return null;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 根据字段名称及字段值查询数据
        /// </summary>
        /// <param name="colName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public virtual List<T> GetEntities(string colName, Object value)
        {
            ConnectResult result = null;
            try
            {
                result = OpenDbConnection();
                string sql = $"select * from {GetTableName()} where {colName}={value}";
                return result?.Connection.GetList<T>(sql).ToList();
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message);
                return null;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }

        }
        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool InsertEntity(T entity)
        {
            ConnectResult result = null;
            try
            {
                if (entity == null)
                    return false;
                result = OpenDbConnection();
                result?.Connection.Insert(entity);
                return true;
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message);
                return false;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 批量插入数据
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public virtual bool InsertEntities(List<T> entities)
        {
            IDbTransaction tran = null;
            ConnectResult result = null;
            try
            {
                if (entities == null || entities.Count == 0)
                    return false;

                result = OpenDbConnection();
                tran = result?.Connection.BeginTransaction();
                foreach (T sss in entities)
                {
                    result?.Connection.Insert(sss);
                }
                tran?.Commit();
                return true;
            }
            catch (Exception ex)
            {
                tran?.Rollback();
                _log.Error(ex.Message);
                return false;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool UpdateEntity(T entity)
        {
            ConnectResult result = null;
            try
            {
                if (entity == null)
                    return false;
                result = OpenDbConnection();
                return result.Connection.Update(entity);
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message);
                return false;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 批量更新数据
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public virtual bool UpdateEntities(List<T> entities)
        {
            IDbTransaction tran = null;
            ConnectResult result = null;
            try
            {
                if (entities == null || entities.Count == 0)
                    return false;
                result = OpenDbConnection();
                tran = result?.Connection.BeginTransaction();
                foreach (T sss in entities)
                {
                    result?.Connection.Update(sss);
                }
                tran?.Commit();
                return true;
            }
            catch (Exception ex)
            {
                tran?.Rollback();
                _log.Error(ex.Message);
                return false;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 插入或更新数据 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool InsertOrUpdateEntity(T entity)
        {
            ConnectResult result = null;
            try
            {
                if (entity == null)
                    return false;
                result = OpenDbConnection();
                result?.Connection.InsertOrUpdate(entity);
                return true;
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message);
                return false;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 批量插入或更新数据
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        public virtual bool SaveEntities(List<T> entities)
        {
            IDbTransaction tran = null;
            ConnectResult result = null;
            try
            {
                if (entities == null)
                    return false;
               
                result = OpenDbConnection();
                if (entities.Count == 0)
                {
                    var res = result?.Connection.DeleteAll<T>();
                    return res == true;
                }
                tran = result?.Connection.BeginTransaction();
                result?.Connection.DeleteAll<T>(); // 删除所有
                foreach (T sss in entities)
                {
                    result?.Connection.InsertOrUpdate(sss);
                }
                tran?.Commit();
                return true;
            }
            catch (Exception ex)
            {
                tran?.Rollback();
                _log.Error(ex.Message);
                return false;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool DeleteEntity(T entity)
        {
            ConnectResult result = null;
            try
            {
                result = OpenDbConnection();
                return result.Connection.Delete(entity);
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message);
                return false;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }
        /// <summary>
        /// 删除所有数据
        /// </summary>
        /// <returns></returns>
        public virtual bool DeleteAllEntities()
        {
            ConnectResult result = null;
            try
            {
                result = OpenDbConnection();

                return result.Connection.DeleteAll<T>();
            }
            catch (Exception ex)
            {
                _log.Error(ex.Message);
                return false;
            }
            finally
            {
                if (result != null)
                {
                    CloseDbConnection(result.Name);
                }
            }
        }




    }
}
